/**
 * 坐骑基础数据采集脚本
 * 功能：发送4423指令获取坐骑列表，然后发送4421指令获取每个坐骑的详细信息
 */

const WebSocket = require('ws');
const fs = require('fs');
const path = require('path');

// 测试配置
const CONFIG = {
    server: {
        host: 'cd521.xin',
        port: 8207,
        protocol: 'ws'
    },
    // 直接使用token连接
    token: '4600d9f37888dfade167489cc392c288', // 替换为你的实际token
};

class MountBaseCollector {
    constructor() {
        this.ws = null;
        this.currentRequest = null; // { command, resolve, reject, timeout }
        this.mountList = []; // 坐骑列表数据
        this.mountDetails = {}; // 坐骑详情数据 { [id]: detail }
    }

    // 发送指令并等待对应响应
    sendCommandAndWait(command, data = null, timeoutMs = 8000) {
        return new Promise((resolve, reject) => {
            try {
                // 防止并发：若上一个请求未结束，则拒绝
                if (this.currentRequest) {
                    return reject(new Error('上一个请求尚未完成'));
                }

                const payload = data ? { c: command, d: data } : { c: command };
                this.ws.send(JSON.stringify(payload));

                const timeout = setTimeout(() => {
                    const err = new Error(`等待 ${command} 响应超时`);
                    if (this.currentRequest && this.currentRequest.reject) {
                        this.currentRequest.reject(err);
                    }
                    this.currentRequest = null;
                }, timeoutMs);

                this.currentRequest = { command, resolve, reject, timeout };
            } catch (err) {
                reject(err);
            }
        });
    }

    // 获取坐骑列表
    async getMountList() {
        console.log('➡️ 获取坐骑列表...');
        try {
            const resp = await this.sendCommandAndWait(4423);
            if (resp && resp.code === 0 && resp.data && Array.isArray(resp.data)) {
                this.mountList = resp.data;
                console.log(`✅ 获取坐骑列表成功，共 ${resp.data.length} 个坐骑`);
                return resp.data;
            } else {
                throw new Error('获取坐骑列表失败或数据格式错误');
            }
        } catch (error) {
            console.error('❌ 获取坐骑列表失败:', error.message);
            throw error;
        }
    }

    // 获取坐骑详情
    async getMountDetail(id) {
        try {
            const resp = await this.sendCommandAndWait(4421, { id });
            if (resp && resp.code === 0 && resp.data) {
                this.mountDetails[id] = resp.data;
                console.log(`✅ 获取坐骑详情成功，ID: ${id}, 名称: ${resp.data.name || '未知'}`);
                return resp.data;
            } else {
                console.log(`⏭️ 坐骑ID ${id} 详情获取失败或数据为空`);
                return null;
            }
        } catch (error) {
            console.log(`⏭️ 坐骑ID ${id} 详情获取失败: ${error.message}`);
            return null;
        }
    }

    // 串行获取所有坐骑详情
    async collectAllMountDetails() {
        console.log('➡️ 开始获取所有坐骑详情...');
        let successCount = 0;
        let skipCount = 0;

        // 从坐骑列表中提取需要查询详情的ID
        const detailIds = new Set();
        this.mountList.forEach(mount => {
            if (mount.hid && mount.hid > 0) {
                detailIds.add(mount.hid);
            }
        });
        detailIds.add(6);
        detailIds.add(7);
        detailIds.add(8);
        detailIds.add(9);

        console.log(`📋 需要查询详情的坐骑ID: ${Array.from(detailIds).join(', ')}`);

        for (const id of detailIds) {
            try {
                const detail = await this.getMountDetail(id);
                if (detail) {
                    successCount++;
                    // 实时保存数据
                    this.writeJsonToFile(this.mountDetails, '坐骑基础数据.json');
                } else {
                    skipCount++;
                }
            } catch (error) {
                skipCount++;
                console.log(`⏭️ 坐骑ID ${id} 跳过（错误: ${error.message}）`);
            }
            // 略微间隔，避免请求过于密集
            await this.delay(200);
        }

        console.log(`✅ 坐骑详情获取完成，成功: ${successCount}，跳过: ${skipCount}`);
    }

    // 延迟工具方法
    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    // 将JSON对象保存为JSON文件
    writeJsonToFile(data, filename, outputDir = './output') {
        try {
            // 确保输出目录存在
            if (!fs.existsSync(outputDir)) {
                fs.mkdirSync(outputDir, { recursive: true });
                console.log(`📁 创建输出目录: ${outputDir}`);
            }

            // 生成完整的文件路径
            const filePath = path.join(outputDir, filename);

            // 将数据转换为格式化的JSON字符串
            const jsonString = JSON.stringify(data, null, 2);

            // 写入文件
            fs.writeFileSync(filePath, jsonString, 'utf8');

            console.log(`💾 数据已保存到文件: ${filePath}`);
            console.log(`📊 数据条数: ${Object.keys(data).length}`);

            return {
                success: true,
                filePath: filePath,
                message: '文件保存成功'
            };

        } catch (error) {
            console.error('❌ 保存文件失败:', error.message);
            return {
                success: false,
                error: error.message,
                message: '文件保存失败'
            };
        }
    }

    // WebSocket连接测试
    async testWebSocketConnection() {
        console.log('🔌 步骤1: WebSocket连接测试...');

        return new Promise((resolve, reject) => {
            try {
                const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${CONFIG.token}`;
                this.ws = new WebSocket(wsUrl);

                this.ws.on('open', async () => {
                    console.log('✅ WebSocket连接成功');

                    // 保持连接的基础指令
                    this.ws.send(JSON.stringify({ c: 3 }));
                    this.ws.send(JSON.stringify({ "c": 5, "d": { "roleId": 12933 } }));
                    this.ws.send(JSON.stringify({ c: 100 }));

                    // 保持ws连接的心跳
                    setInterval(() => {
                        this.ws.send(JSON.stringify({ c: 100 }));
                    }, 20000);

                    try {
                        // 1. 获取坐骑列表
                        await this.getMountList();

                        // 2. 获取所有坐骑详情
                        await this.collectAllMountDetails();

                        console.log('🎉 坐骑基础数据采集完成');
                        resolve();
                    } catch (error) {
                        console.error('❌ 采集过程中发生错误:', error.message);
                        resolve();
                    }
                });

                this.ws.on('error', (error) => {
                    console.log('❌ WebSocket连接失败:', error.message);
                    reject(error);
                });

                this.ws.on('close', () => {
                    console.log('🔌 WebSocket连接已关闭');
                });

                this.ws.on('message', (data) => {
                    try {
                        const message = JSON.parse(data);

                        // 处理 4423 和 4421 的响应
                        if ((message.act_id == 4423 || message.act_id == 4421) && this.currentRequest) {
                            clearTimeout(this.currentRequest.timeout);
                            const { resolve } = this.currentRequest;
                            this.currentRequest = null;
                            resolve(message);
                        }
                    } catch (error) {
                        console.error('❌ 消息解析失败:', data);
                    }
                });

            } catch (error) {
                reject(error);
            }
        });
    }

    // 运行完整采集流程
    async runCollection() {
        console.log('🚀 开始坐骑基础数据采集...\n');
        console.log('采集目标：发送4423指令获取坐骑列表 → 发送4421指令获取每个坐骑详情 → 保存数据\n');

        try {
            // 1. 建立WebSocket连接并开始采集
            await this.testWebSocketConnection();

            console.log('\n📊 采集完成统计:');
            console.log(`   坐骑列表数量: ${this.mountList.length}`);
            console.log(`   坐骑详情数量: ${Object.keys(this.mountDetails).length}`);
            console.log(`   输出文件: ./output/坐骑基础数据.json`);

        } catch (error) {
            console.error('❌ 采集过程中发生错误:', error.message);
        }
    }
}

// 运行采集
async function main() {
    console.log('🎯 坐骑基础数据采集模式');
    console.log('   专注于采集：4423获取列表 → 4421获取详情 → 保存数据\n');

    const collector = new MountBaseCollector();
    await collector.runCollection();
}

// 如果直接运行此脚本
if (require.main === module) {
    main().catch((error) => {
        console.error('💥 采集脚本执行失败:', error.message);
        process.exit(1);
    });
}

module.exports = MountBaseCollector;
